package cz.tomasdvorak.cars.wicket.components.auth;

import org.apache.wicket.authorization.strategies.role.RoleAuthorizationStrategy;
import org.apache.wicket.authorization.strategies.role.IRoleCheckingStrategy;
import org.apache.wicket.authorization.strategies.role.Roles;
import org.apache.wicket.authorization.IAuthorizationStrategy;
import org.apache.wicket.authorization.Action;
import org.apache.wicket.Component;
import org.apache.wicket.MetaDataKey;

/**
 * Autorizacni strategie, ktera umoznuje prez metadata component urcit jejich prava na renderovani.
 * Protoze {@link RoleAuthorizationStrategy} ma metody finalni, musim to delegovat a zde implementovat
 * jen interface.
 */
public class MetadataAuthorizationStrategy implements IAuthorizationStrategy {

    private final RoleAuthorizationStrategy delegate;

    public static final MetaDataKey<String[]> META_DATA_KEY = new MetaDataKey<String[]>() {
    };

    private final IRoleCheckingStrategy strategy;

    public MetadataAuthorizationStrategy(IRoleCheckingStrategy roleCheckingStrategy) {
        delegate = new RoleAuthorizationStrategy(roleCheckingStrategy);
        strategy = roleCheckingStrategy;
    }


    public <T extends Component> boolean isInstantiationAuthorized(Class<T> componentClass) {
        return delegate.isInstantiationAuthorized(componentClass);
    }

    public boolean isActionAuthorized(Component component, Action action) {
        if (action == Component.RENDER) {
            String[] roles = component.getMetaData(META_DATA_KEY);
            if (roles == null) {
                return delegate.isActionAuthorized(component, action);
            } else {
                return strategy.hasAnyRole(new Roles(roles));
            }
        }
        return delegate.isActionAuthorized(component, action);
    }

    public static Component authorize(Component component, String... roles) {
        component.setMetaData(META_DATA_KEY, roles);
        return component;
    }
}
